import sys
import traceback
from redis import Redis
import json
from app.schemas.risk_schema import FeeRiskSchema
from sqlalchemy.orm import Session
from app.common.enums import algo_types
from app.common.enums.resp_enum import ErrTypes
from app.common import exceptions
from app import utils
from app.config import conf
#from app import utils
from app.services.channel import get_channel_fees
from app.common.exceptions import GenericException

import logging
logger = logging.getLogger(__name__)


IP_WHITE_LIST_KEY = 'ip_white_list'


CARD_DATA_KEY = 'card_data'

DAY_EX_SECONDS = 60 * 60 * 24 * 2   # 2天
MONTH_EX_SECONDS = 60 * 60 * 24 * 60 # 2个月\
LIMIT_TRANS_AMOUNT = int(conf.LIMIT_TRANS_AMOUNT)
LIMIT_DAY_AMOUNT = int(conf.LIMIT_DAY_AMOUNT)
LIMIT_MONTH_AMOUNT = int(conf.LIMIT_MONTH_AMOUNT)

##################### 交易限额 ####################

def is_in_limit_trans_amount(db: Session, r: Redis, card_no, amount):
    logger.info('>> is_in_limit_trans_amount')
    try:
        if amount > LIMIT_TRANS_AMOUNT:
            raise GenericException(ErrTypes.risk_over_card_trans_limit)
        elif not is_in_limit_day_amount(db, r, card_no, amount):
            raise GenericException(ErrTypes.risk_over_card_day_limit)
        elif not is_in_limit_month_amount(db, r, card_no, amount):
            raise GenericException(ErrTypes.risk_over_card_month_limit)
        else:
            return True
    except GenericException as err:
        #logger.error(err)
        raise GenericException(err.error_type, message=err.message, data=err.data)
    except Exception as err:
        logger.error('单卡限额检查错误')
        exc_type, exc_value, exc_obj = sys.exc_info()
        traceback.print_exception(exc_type,exc_value,exc_obj,limit=3,file=sys.stdout)
        raise GenericException(ErrTypes.trans_create_fail)
    

def is_in_limit_trans_amount2(db: Session, r: Redis, amount):
    logger.info('>> is_in_limit_trans_amount')
    if amount > LIMIT_TRANS_AMOUNT:
        raise GenericException(ErrTypes.risk_over_card_trans_limit)
    else:
        return True

def is_in_limit_day_amount(db: Session, r: Redis, card_no, amount):
    logger.info('>> is_in_limit_day_amount')
    trans_date = utils.get_time_now(type=5)
    key = f'{CARD_DATA_KEY}:day:{card_no}:{trans_date}'
    card_data = {}
    data_js = r.get(key)
    if data_js:
        card_data = json.loads(data_js)
        new_amount = card_data.get('amount') + amount
        if new_amount > LIMIT_DAY_AMOUNT:
            logger.error(f'单卡日交易超出限额')
            raise GenericException(ErrTypes.risk_over_card_day_limit)
        else:
            return True
    else:
        return True
    

def is_in_limit_month_amount(db: Session, r: Redis, card_no, amount):
    logger.info('>> is_in_limit_day_amount')
    trans_month = utils.get_time_now(type=6)
    key = f'{CARD_DATA_KEY}:day:{card_no}:{trans_month}'
    card_data = {}
    data_js = r.get(key)
    if data_js:
        card_data = json.loads(data_js)
        new_amount = card_data.get('amount') + amount
        if new_amount > LIMIT_DAY_AMOUNT:
            logger.error(f'单卡月交易超出限额')
            raise GenericException(ErrTypes.risk_over_card_month_limit)
        else:
            return True
    else:
        return True

def is_ip_in_white_list(r: Redis, ip_addr: str) -> bool:
    try:
        v = r.get(f'{IP_WHITE_LIST_KEY}:{ip_addr}')
        if v:
            return True
        else:
            return False
    except Exception as err:
        raise GenericException(ErrTypes.system_error)


